﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Lab6
{
    [Serializable]
    public abstract class Shape
    {

        protected List<Point> points = new List<Point>();


        public Shape()
        {
            FillColor = Color.Blue;
        }

        // Draw itself, decendants should override it.
        public abstract void Draw(Graphics g);
        public abstract bool IsEnd(Point p);

        // move last point
        public void RemoveAt(int index) 
        {
            points.RemoveAt(index);
        
        }

        public void AddPoint(Point p)
        {
            points.Add(p);
        }

        public int NumOfPoints
        {
            get { return points.Count; }
        }

        public Point this[int x]
        {
            get { return points[x]; }
            set
            {
                points[x] = value;
            }
        }


        public void Offset(int x, int y)
        {
            for (int i = 0; i < points.Count; i++)
            {
                Point p = points[i];
                p.Offset(x, y);
                points[i] = p;
            }
        }
        public abstract bool PtInShape(Point p);


        public Rectangle GetBoundingRect()
        {
            //find the min coordinate for each point of shape
            int xUL = Int32.MaxValue, yUL = Int32.MaxValue, xBR = 0, yBR = 0;

            foreach (Point p in points)
            {

                if (p.X < xUL)
                    xUL = p.X;
                if (p.Y < yUL)
                    yUL = p.Y;

                if (p.X > xBR)
                    xBR = p.X;
                if (p.Y > yBR)
                    yBR = p.Y;
            }

            return new Rectangle(xUL, yUL, xBR - xUL, yBR - yUL);


        }
        public Color FillColor { get; set; }
    }

    // A rectangle
    [Serializable]
    public class Rect : Shape
    {

        public override bool PtInShape(Point p)
        {
            if (NumOfPoints == 2)
            {
                Rectangle rect = GetBoundingRect();
                return p.X > rect.Left && p.X < rect.Right && p.Y > rect.Top && p.Y < rect.Bottom;
            }
            return false;
        }

        public override void Draw(Graphics g)
        {
            if (NumOfPoints == 2)
            {
                Pen pen = new Pen(new SolidBrush(FillColor));
                g.DrawRectangle(pen, GetBoundingRect());
            }
        }

        public override bool IsEnd(Point p)
        {
            return NumOfPoints == 2;
         
        }



    }
    [Serializable]
    public class Polygon : Shape
    {
        public override bool PtInShape(Point p)
        {
            if (NumOfPoints >= 3)
            {
                Rectangle rect = GetBoundingRect();
                return p.X > rect.Left && p.X < rect.Right && p.Y > rect.Top && p.Y < rect.Bottom;
            }
            return false;
        }

        public override void Draw(Graphics g)
        {
            if (NumOfPoints >= 2)
            {
                Pen pen = new Pen(new SolidBrush(FillColor));
                g.DrawPolygon(pen, points.ToArray());
            }
        }

        public override bool IsEnd(Point p)
        {
            return Math.Abs(p.X - points[0].X) < 10 && Math.Abs(p.Y - points[0].Y) < 10;
        }

    }


}
